﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FAP.Threading.ThreadPools.TaskItems;
using log4net;
using System.Threading;

namespace FAP.Cores.Task
{
    /// <summary>
    /// A sample task
    /// </summary>
    public class FapTask : ITaskItem
    {
        /// <summary>
        /// Logger
        /// </summary>
        private ILog m_log = LogManager.GetLogger(typeof(FapTask));
        /// <summary>
        /// Callback when finished job
        /// </summary>
        /// <param name="sender">Owner class</param>
        /// <param name="result">The result of work</param>
        public delegate void onFinishedHandeler(object sender, object result);
        public delegate void onErrorHandeler(object sender, object result);
        public delegate void onChangeStatusHandeler(object sender, object result);
        /// <summary>
        /// Event finished
        /// </summary>
        public onFinishedHandeler onFinished = null;
        public onErrorHandeler onError = null;
        public onChangeStatusHandeler onChangeStatus = null;
        /// <summary>
        /// Work's priority
        /// </summary>
        private TaskItemPriority _priority;
        /// <summary>
        /// Time to repeat - by second
        /// </summary>
        public int TimeToRepeat = 0;

        public TaskItemPriority Priority
        {
            get { return _priority; }
            set { _priority = value; }
        }
        /// <summary>
        /// Work's index
        /// </summary>
        private int _taskIndex;

        protected int _iStatus = 0;

        private string m_taskName = "";

        public string TaskName
        {
            get { return m_taskName; }
            set { m_taskName = value; }
        }

        public int Status
        {
            get { return _iStatus; }
        }
        protected void WaitCaptcha()
        {
            _iStatus = 4;
        }
        /*
         * 0: Waiting
         * 1: Working
         * 2: Finished
         * 3: Error
         * 4: Wait captcha
         * */

        public int TaskIndex
        {
            get { return _taskIndex; }
            set { _taskIndex = value; }
        }

        public void DoWork()
        {
            while (true)
            {
                m_log.Info(string.Format("{1}: Working task {0}", _taskIndex, this.TaskName));
                FAP.Cores.Console.FapConsole.WriteLine(string.Format("{1}: Working task {0}", _taskIndex, this.TaskName), 1);
                this._iStatus = 1;
                if (onChangeStatus != null)
                    this.onChangeStatus(this, _iStatus);
                object result = null;
                try
                {
                    result = this.RunIt();
                    if (_iStatus == 4)
                    {
                        return;
                    }
                    this._iStatus = 2;
                    if (onChangeStatus != null)
                        this.onChangeStatus(this, _iStatus);
                    if (onFinished != null)
                    {
                        m_log.Info(string.Format("{1}: Finished task {0}", _taskIndex, this.TaskName));
                        FAP.Cores.Console.FapConsole.WriteLine(string.Format("{1}: Finished task {0}", _taskIndex, this.TaskName), 1);
                        this.onFinished(this, result);
                        
                    }
                    m_log.Info(string.Format("{1}: Waiting({0}s)", this.TimeToRepeat, this.TaskName));
                    FAP.Cores.Console.FapConsole.WriteLine(string.Format("{1}: Waiting({0}s)", this.TimeToRepeat, this.TaskName), 1);
                    if (this.TimeToRepeat > 0)
                    {
                        Thread.Sleep(this.TimeToRepeat * 1000);
                    }
                    else
                    {
                        FAP.Cores.Threading.ThreadControl.m_lstTask.Remove(this);
                        m_log.Info(string.Format("{1}: Removed task {0}", _taskIndex, this.TaskName));
                        FAP.Cores.Console.FapConsole.WriteLine(string.Format("{1}: Removed task {0}", _taskIndex, this.TaskName), 1);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    if (onError != null)
                    {
                        m_log.Error(string.Format("{1}: Error task {0}", _taskIndex, this.TaskName), ex);
                        FAP.Cores.Console.FapConsole.WriteLine(string.Format("{1}: Error task {0}", _taskIndex, this.TaskName), 4);
                        this._iStatus = 3;
                        if (onChangeStatus != null)
                            this.onChangeStatus(this, _iStatus);
                        this.onError(this, ex);
                        FAP.Cores.Threading.ThreadControl.m_lstTask.Remove(this);
                        m_log.Info(string.Format("{1}: Removed task {0}", _taskIndex, this.TaskName));
                        FAP.Cores.Console.FapConsole.WriteLine(string.Format("{1}: Removed task {0}", _taskIndex, this.TaskName), 4);
                        break;
                    }
                }
                
            }
        }
        /// <summary>
        /// All work push in
        /// </summary>
        public virtual object RunIt()
        {
            return null;
        }
    }
}
